#include "strategyconditionbase.h"
#include <QtConcurrent>


/*
void NormalDetectStrategy::execute(NormalDetectBase & NormalDetectBase, SteelInfo *steel, int level)
{
    QList<ClientDefect* > dlist; //存储被被判定的缺陷

    foreach (ClientDefect *defect, steel->ClientDefect1ist)
    {
        //返回具体的缺陷条件{ [一级] [二级] [三级] }
        DefectLvDetectWrapper* conditionInfoList =  NormalDetectBase.findDefectByName(defect->getDefectName(),steel->getSteelType());
        if(conditionInfoList)
        {
            int length = 0;
            int width = 0;
            int times = 0;
            if(level == 1){
                length = conditionInfoList->findElementByName("一级")->GetLength();
                width = conditionInfoList->findElementByName("一级")->GetWidth();
                times = conditionInfoList->findElementByName("一级")->GetTimes();
                if(defect->getWidth()>= width && defect->getHeight() >=length){
                    defect->SetDefectLevel(level);
                }
            }else if(level == 2){
                length = conditionInfoList->findElementByName("二级")->GetLength();
                width = conditionInfoList->findElementByName("二级")->GetWidth();
                times = conditionInfoList->findElementByName("二级")->GetTimes();
                if(defect->getWidth()>= width && defect->getHeight() >=length){
                    defect->SetDefectLevel(level);
                }
            }else if(level == 3){
                length = conditionInfoList->findElementByName("三级")->GetLength();
                width = conditionInfoList->findElementByName("三级")->GetWidth();
                times = conditionInfoList->findElementByName("三级")->GetTimes();
                if(defect->getWidth()>= width && defect->getHeight() >=length){
                    defect->SetDefectLevel(level);
                }
            }else{
                defect->SetDefectLevel(level);
                continue;
            }
            dlist.append(defect);
        }
    }

    //统计一二三级出现的次数
    int totalone = 0;
    int tataltwo = 0;
    int tatalthree = 0;
    foreach (ClientDefect * cd, dlist) {
        if(auto condtion = NormalDetectBase.findDefectByName(cd->getDefectName(),steel->getSteelType())){
            if(level == 1 && condtion->findElementByName("一级")->GetTimes() > steel->getTotalDefectNumber(cd->getDefectName(),1)){
                steel->setLevel(1);
                QString info = QString(" %1 : 缺陷:(%3) %2 数量超过设定的长宽阈值,该卷被判定为:1").arg(steel->getSteelName()).arg(cd->getDefectName()).arg(cd->getDefectNo());
                qDebug()<<info;
                //steel->infos.append(info);
            }
            if(level == 2 && condtion->findElementByName("二级")->GetTimes() > steel->getTotalDefectNumber(cd->getDefectName(),1)){
                steel->setLevel(2);
                QString info = QString(" %1 : 缺陷:(%3) %2 数量超过设定的长宽阈值,该卷被判定为:2").arg(steel->getSteelName()).arg(cd->getDefectName()).arg(cd->getDefectNo());
                steel->infos.append(info);
                qDebug()<<info;
            }
            if(level == 3 && condtion->findElementByName("三级")->GetTimes() > steel->getTotalDefectNumber(cd->getDefectName(),1)){
                steel->setLevel(3);
                QString info = QString(" %1 : 缺陷(%3): %2 数量超过设定的长宽阈值,该卷被判定为:3").arg(steel->getSteelName()).arg(cd->getDefectName()).arg(cd->getDefectNo());
                steel->infos.append(info);
                qDebug()<<info;
            }
        }
    }

}




//---------------------------------------------------------
void BesideDetectStrategy::execute(NormalDetectBase & NormalDetectBase, SteelInfo *steel, int level)
{
    //BesideDetectBase *besideCondtion = static_cast<BesideDetectBase*>(&NormalDetectBase);

    foreach (ClientDefect *defect, steel->ClientDefect1ist)
    {
        if(DefectLvDetectWrapper* conditionInfoList =  NormalDetectBase.findDefectByName(defect->getDefectName(),steel->getSteelType())){

            if(level == 1){
                if(defect->getLeftinSteel() > conditionInfoList->findElementByName("一级")->GetLength()
                    || defect->getRightintSteel() > conditionInfoList->findElementByName("一级")->GetLength() )
                {
                    defect->SetDefectLevel(level);
                    steel->setLevel(level);

                    QString info = QString(" %1 : 缺陷: %2 数量超过设定的边部阈值,该卷被判定为:1").arg(steel->getSteelName()).arg(defect->getDefectName());
                    //steel->infos.append(info);
                    qDebug()<<info;
                }
            }else if(level == 2){
                if(defect->getLeftinSteel() > conditionInfoList->findElementByName("二级")->GetLength()
                    || defect->getRightintSteel() > conditionInfoList->findElementByName("二级")->GetLength() )
                {
                    defect->SetDefectLevel(level);
                    steel->setLevel(level);

                    QString info = QString(" %1 : 缺陷: %2 数量超过设定的边部阈值,该卷被判定为:2").arg(steel->getSteelName()).arg(defect->getDefectName());
                    steel->infos.append(info);
                    qDebug()<<info;
                }
            }else if(level == 3){
                if(defect->getLeftinSteel() > conditionInfoList->findElementByName("三级")->GetLength()
                    ||  defect->getRightintSteel() > conditionInfoList->findElementByName("三级")->GetLength() )
                {
                    defect->SetDefectLevel(level);
                    steel->setLevel(level);

                    QString info = QString(" %1 : 缺陷: %2 数量超过设定的边部阈值,该卷被判定为:3").arg(steel->getSteelName()).arg(defect->getDefectName());
                    steel->infos.append(info);
                    qDebug()<<info;
                }
            }
        }
    }


}

//---------------------------------------------------------


double FrequencyDetectStrategy::calculateDistance(const ClientDefect &d1, const ClientDefect &d2) const
{
    return std::sqrt(std::pow(d1.getLeftinSteel() - d2.getLeftinSteel(), 2) + std::pow(d1.getRightintSteel() - d2.getRightintSteel(), 2));
}

void FrequencyDetectStrategy::calculateFrequence(QList<ClientDefect*> list, NormalDetectBase& NormalDetectBaset, SteelInfo *steel, int level, int camNo){
     //存储一个相机存在多个需要频率判级的缺陷
     QMap<QString,int> map;

     for (int i = 0; i < list.size(); ++i) {
         int totalCount = 0;
         for (int j = 0; j < list.size(); ++j) {

             if(i!=j&& list[i]->getDefectName() == list[j]->getDefectName()){
                 int reqLength = 0;
                 if(level == 1){
                    reqLength = NormalDetectBaset.findDefectByName(list[i]->getDefectName(),steel->getSteelType())->findElementByName("一级")->GetLength();
                 }else if(level == 2){
                    reqLength = NormalDetectBaset.findDefectByName(list[i]->getDefectName(),steel->getSteelType())->findElementByName("二级")->GetLength();
                 }else if(level == 3){
                    reqLength = NormalDetectBaset.findDefectByName(list[i]->getDefectName(),steel->getSteelType())->findElementByName("三级")->GetLength();
                 }else{
                    continue;
                 }

                 double distance = calculateDistance(*list[i],*list[j]);
                 if(distance <= reqLength ){
                     totalCount += 1;
                }
            }
        }
         if(map.contains(list[i]->getDefectName())){
            if(map.value(list[i]->getDefectName()) < totalCount ){
                //只统计频率最高的缺陷
                map[list[i]->getDefectName()] = totalCount;
            }
         }else{
             map.insert(list[i]->getDefectName(),1);
         }
    }

     foreach (const QString &key, map.keys()) {
        int reqFrequence = 0;
        if(level == 1){
            reqFrequence = NormalDetectBaset.findDefectByName(key,steel->getSteelType())->findElementByName("一级")->GetTimes();
        }else if(level == 2){
            reqFrequence = NormalDetectBaset.findDefectByName(key,steel->getSteelType())->findElementByName("二级")->GetTimes();
        }else if(level == 3){
            reqFrequence = NormalDetectBaset.findDefectByName(key,steel->getSteelType())->findElementByName("三级")->GetTimes();
        }else{
            continue;
        }


        if(map.value(key) > reqFrequence){
            steel->setLevel(level);
            if(level >= 2){
                QString str = QString(" %1 : 缺陷: %2 在相机: %3  数量超过设定的频率阈值(%4),该卷被判定为:%5").arg(steel->getSteelName()).arg(key).arg(camNo).arg(map.value(key)).arg(level);
                steel->infos.append(str);
                qDebug()<<str;
            }
        }
     }

}



void FrequencyDetectStrategy::execute(NormalDetectBase & NormalDetectBase, SteelInfo *steel, int level)
{
    //FrequencyDetectBase *frequenceCondtion = static_cast<FrequencyDetectBase*>(&NormalDetectBase);

    //存储各个相机需要做频率判断的缺陷：不需要对每个相同的缺陷进行重复的判断 只需要对不同的缺陷进行对比
    QList<ClientDefect*> cam1;
    QList<ClientDefect*> cam2;
    QList<ClientDefect*> cam3;
    QList<ClientDefect*> cam4;



    foreach (ClientDefect *defect, steel->ClientDefect1ist) {
        if(DefectLvDetectWrapper* conditionInfoList =  NormalDetectBase.findDefectByName(defect->getDefectName(),steel->getSteelType())){

            if(defect->getCameraNo() == 1){
                cam1.append(defect);
            }else if(defect->getCameraNo() == 2){
                cam2.append(defect);
            }else if(defect->getCameraNo() == 3){
                cam3.append(defect);
            }else if(defect->getCameraNo() == 4){
                 cam4.append(defect);
            }else{
                continue;
            }
        }
    }

    if(cam1.size() > 0 || cam2.size() > 0 || cam3.size() > 0 || cam4.size() > 0){
        calculateFrequence(cam1,NormalDetectBase,steel,level,1);
        calculateFrequence(cam2,NormalDetectBase,steel,level,2);
        calculateFrequence(cam3,NormalDetectBase,steel,level,3);
        calculateFrequence(cam4,NormalDetectBase,steel,level,4);
    }

}






//---------------------------------------------------------

void calculateLength(QMap<QString,QList<ClientDefect*>> map,NormalDetectBase & NormalDetectBase,SteelInfo *steel,int lv){

    foreach (const QString &dName, map.keys()) {
        if(DefectLvDetectWrapper* conditionInfo = NormalDetectBase.findDefectByName(dName,steel->getSteelType())){
            //获取条件
            int ConditionLength = 0;
            int WidthThreshold = 0;

            if(lv == 1){
                ConditionLength  = conditionInfo->findElementByName("一级")->GetLength();
                WidthThreshold = conditionInfo->findElementByName("一级")->GetWidth();
            }else if(lv == 2){
                ConditionLength  = conditionInfo->findElementByName("二级")->GetLength();
                WidthThreshold = conditionInfo->findElementByName("二级")->GetWidth();
            }else if(lv == 3){
                ConditionLength  = conditionInfo->findElementByName("三级")->GetLength();
                WidthThreshold = conditionInfo->findElementByName("三级")->GetWidth();
            }else{
                continue;
            }


            int calLength = 0;
            qDebug()<<map.value(dName).size();
            if(map.value(dName).size() >= 2){
                //计算累加长度,默认值是元素的第一个长度
                calLength = qAbs(qAbs(map.value(dName)[0]->getTopinSteel()) - qAbs(map.value(dName)[0]->getBottomInSteel()));

                for (int i = 0; i < map.value(dName).size() - 1 ; ++i) {
                    ClientDefect* CurDefect = map.value(dName)[i];
                    ClientDefect* next = map.value(dName)[i+1];
                    //缺陷小于width阈值的 认为是同一个缺陷
                    if(
                        qAbs(qAbs(CurDefect->getLeftinSteel()) - qAbs(next->getRightintSteel()) < WidthThreshold) ||
                        qAbs(qAbs(CurDefect->getRightintSteel()) - qAbs(next->getRightintSteel())< WidthThreshold)
                        )
                    {
                        int nextLength = qAbs(qAbs(next->getTopinSteel()) - qAbs(next->getBottomInSteel()));
                        calLength += nextLength;
                    }
                }
                int camNo = map.value(dName)[0]->getCameraNo();
                if(calLength > ConditionLength){
                    steel->setLevel(lv);
                    if(lv >= 2){
                        QString str = QString(" %1 : 在相机: %2 长度超过设定阈值被判定为:%3)").arg(steel->getSteelName()).arg(camNo).arg(lv);
                        steel->infos.append(str);
                        qDebug()<<str;
                    }

                }

            }
        }
    }
}


void VerticalLengthDetectStrategy::calculateLengthByDefectName(QList<ClientDefect*> cam,NormalDetectBase & NormalDetectBase,SteelInfo *steel,int lv)
{
    //根据缺陷名称存储多个不同的元素
    QMap<QString,QList<ClientDefect*>> map;

    foreach (ClientDefect *defect, cam) {
        if(map.contains(defect->getDefectName())){
            qDebug()<<map.value(defect->getDefectName()).size();
            map[defect->getDefectName()].append(defect);
        }
        else
        {
            QList<ClientDefect*>l;
            l.append(defect);
            map.insert(defect->getDefectName(),l);
        }
    }

    calculateLength(map,NormalDetectBase,steel,lv);
}


void VerticalLengthDetectStrategy::execute(NormalDetectBase & NormalDetectBase, SteelInfo *steel, int level)
{
     //VerticalLengthDetectBase *verticalCondtion = static_cast<VerticalLengthDetectBase*>(&NormalDetectBase);


    //通卷率 : 一个缺陷在钢板的总体长度
    //存在缺陷长度重叠问题
    //按相机区分缺陷 通过给定的阈值 认为是否是同一个缺陷

    QList<ClientDefect*> cam1;
    QList<ClientDefect*> cam2;
    QList<ClientDefect*> cam3;
    QList<ClientDefect*> cam4;


    foreach (ClientDefect *defect, steel->ClientDefect1ist) {
        if(DefectLvDetectWrapper* conditionInfoList =  NormalDetectBase.findDefectByName(defect->getDefectName(),steel->getSteelType())){

            if(defect->getCameraNo() == 1){
                cam1.append(defect);
            }else if(defect->getCameraNo() == 2){
                cam2.append(defect);
            }else if(defect->getCameraNo() == 3){
                cam3.append(defect);
            }else if(defect->getCameraNo() == 4){
                cam4.append(defect);
            }else{
                continue;
            }
        }
    }

    if(cam1.size() > 0 || cam2.size() > 0 || cam3.size() > 0 ||cam4.size()>0){
        calculateLengthByDefectName(cam1,NormalDetectBase,steel,level);
        calculateLengthByDefectName(cam2,NormalDetectBase,steel,level);
        calculateLengthByDefectName(cam3,NormalDetectBase,steel,level);
        calculateLengthByDefectName(cam4,NormalDetectBase,steel,level);
    }

}



//---------------------------------------------------------
void DirectDetectStrategy::execute(NormalDetectBase & NormalDetectBase, SteelInfo *steel, int level)
{

    //DirectLevelBase *directCondtion = static_cast<DirectLevelBase*>(&NormalDetectBase);
    foreach (ClientDefect *defect, steel->ClientDefect1ist) {
        if(DefectLvDetectWrapper* conditionInfoList = NormalDetectBase.findDefectByName(defect->getDefectName(), steel->getSteelType())){
            defect->SetDefectLevel(3);
            steel->setLevel(3);
            QString info = QString(" %1 : 出现严重缺陷 因为缺陷: %2  判定为:3 ").arg(steel->getSteelName()).arg(defect->getDefectName());
            steel->infos.append(info);
            qDebug()<<info;
        }
    }
}
*/
